import * as Cesium from 'cesium';
import BaseDraw from './common/BaseDraw';
import * as CesiumCoord from './common/CesiumCrood';
import * as CesiumCaculater from './common/CesiumCaculater';
import GroupEntityCollection from '../../Common/GroupEntityCollection';
import { v4 } from 'uuid';

export default class DrawPolygon extends BaseDraw {
    constructor(viewer, tip) {
        super(viewer);
        this.viewer = viewer;
        this.tip = tip; // 提示DOM
        // 事件对象，每种类型的事件只能注册一次
        this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        this.entityCollection = new GroupEntityCollection(viewer); // 集合
        
        this.resetDraw()
    }
    // 重置绘制中间量
    resetDraw() {
        this.groupId = v4(); // 当前绘制的groupID
        this.labelEntity = null; // 当次绘制的-标签实例
        this.polylineEntity = null; // 当次绘制的-折线实例
        this.polygonEntry = null; // 当次绘制的-多边形实例
        this.positionList = []; // 当次绘制的笛卡尔数组
    }
    getAllEntity() {
        return this.entityCollection.getAllEntities();
    }
    // 关闭 CallbackProperty的计算，取最后一次的结果
    removeCallbackProperty() {
        if (this.labelEntity) {
            this.labelEntity.position = this.labelEntity.position.getValue();
            this.labelEntity.label.text = this.labelEntity.label.text.getValue();
        }
        if (this.polygonEntry) {
            this.polygonEntry.polygon.hierarchy = this.polygonEntry.polygon.hierarchy.getValue();
        }
    }
    // 生成测量 Label实体
    createLabelEntity() {
        const _this = this;
        const positionList = this.positionList;
        const entity = new Cesium.Entity({
            position: new Cesium.CallbackProperty(() => {
                if (positionList.length > 2) {
                    const pointList = CesiumCoord.cartesian3ToLonLatHeightArray(positionList); // 转化为经纬度坐标
                    // 返回几何中心
                    const center = CesiumCaculater.centerOfMass([[...pointList, pointList[0]]]);
                    return center;
                } else {
                    return positionList[positionList.length - 1];
                }
            }, false),
            label: {
                text: new Cesium.CallbackProperty(() => {
                    // 动态改变标签显示
                    if (positionList.length > 2) {
                        // 返回面积
                        const pointList = CesiumCoord.cartesian3ToLonLatHeightArray(positionList); // 转化为经纬度坐标
                        const area = CesiumCaculater.area([[...pointList, pointList[0]]]);
                        if (area > 1000000) {
                            return '面积:' + (area / 1000000).toFixed(2) + '平方公里';
                        } else {
                            return '面积:' + area.toFixed(2) + '平方米';
                        }
                    } else {
                        return '0';
                    }
                }, false),
                font: '20px',
                color: Cesium.Color.RED,
                pixelOffset: new Cesium.Cartesian2(0, 0),
                fillColor: Cesium.Color.WHITE,
                showBackground: true,
                backgroundColor: Cesium.Color.BLUE,
            },
        });
        return entity;
    }
    // 生成辅助线实体
    createPolylineEntity() {
        const positionList = this.positionList;
        const entity = new Cesium.Entity({
            polyline: {
                positions: new Cesium.CallbackProperty(() => positionList, false),
                clampToGround: true,
                material: Cesium.Color.RED,
                width: 1,
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
        });
        return entity;
    }
    // 生成多边形实体
    createPolygonEntity() {
        const _this = this;
        const positionList = this.positionList;
        const entity = new Cesium.Entity({
            polygon: {
                hierarchy: new Cesium.CallbackProperty(
                    () => new Cesium.PolygonHierarchy(positionList),
                    false
                ),
                perPositionHeight: false,
                // extrudedHeightReference: 2,
                material: Cesium.Color.YELLOW.withAlpha(0.5),
                outline: true,
                outlineColor: Cesium.Color.RED,
                outlineWidth: 10,
                disableDepthTestDistance: Number.POSITIVE_INFINITY, // 指定将在距相机多远的距离显示此多边形。
            },
        });

        return entity;
    }
}

/**
 * 开始绘制点
 * @param {* 是否显示测量Label} showMeasureLabel
 * @param {* 是否连续绘制} continuousDraw
 */
DrawPolygon.prototype.startDraw = function (showMeasureLabel = true, continuousDraw = true) {
    const _this = this;
    this.resetDraw(); // 重置绘制中间量
    this.tip.show('单击开始绘制');
    // 左键点击事件
    this.handler.setInputAction(event => {
        const cartesian = CesiumCoord.ScreenToCartesian3(_this.viewer, event.position); // 屏幕坐标转世界坐标
        if (!Cesium.defined(cartesian)) return;
        _this.positionList.push(cartesian.clone());
        // 新增测量标注
        if (showMeasureLabel && !_this.labelEntity && _this.positionList.length > 2) {
            _this.labelEntity = _this.createLabelEntity();
            _this.entityCollection.add(_this.labelEntity, _this.groupId);
        }
        // 绘制多边形
        if (!_this.polygonEntry) {
            _this.polygonEntry = _this.createPolygonEntity();
            _this.entityCollection.add(_this.polygonEntry, _this.groupId);
        }
        // 绘制时的辅助线 临时的
        if (!_this.polylineEntity) {
            _this.polylineEntity = _this.createPolylineEntity();
            _this.viewer.entities.add(_this.polylineEntity);
        }
        _this.tip.changeText('右键结束绘制');
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    // 鼠标移动事件
    this.handler.setInputAction(event => {
        if (this.polygonEntry) {
            const cartesian = CesiumCoord.ScreenToCartesian3(_this.viewer, event.endPosition); // 屏幕坐标转世界坐标
            if (!Cesium.defined(cartesian)) return;
            const positionList = _this.positionList;
            if (positionList.length === 1) {
                positionList.push(cartesian.clone());
            } else if (positionList.length >= 2) {
                positionList.pop();
                positionList.push(cartesian.clone());
            }
        }
        const { x, y } = event.endPosition;
        _this.tip.moveTipDOMPosition(x, y); // 改变 TipDOM 位置
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    // 右键点击事件
    this.handler.setInputAction(event => {
        this.endDraw();
        // 连续绘制
        if (continuousDraw) {
            this.startDraw();
        }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};

/**
 * 结束绘制点
 */
DrawPolygon.prototype.endDraw = function () {
    // 做一下判断 如果点位少于4个，则不构成
    if (this.positionList.length < 4) {
        // 删除这次绘制结果
        this.entityCollection.remove(this.groupId);
    } else {
        this.positionList.pop(); // 删除最后一个点位
    }
    // 如果辅助线存在,移除辅助线
    if (this.polylineEntity) {
        this.viewer.entities.remove(this.polylineEntity);
    }
    this.removeCallbackProperty(); // 删除callback的持续计算
    this.tip.close();
    // 删除事件
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};
/**
 * 清除绘制的点
 */
DrawPolygon.prototype.removeDraw = function () {
    this.entityCollection.removeAll();
};

/**
 * 开始绘制点, Promise 方式，连续绘制放在了外部
 * @param {* 是否显示测量Label} showMeasureLabel
 */
DrawPolygon.prototype.drawPromise = function (showMeasureLabel = true) {
    const _this = this;
    return new Promise((resolve, reject) => {
        this.resetDraw(); // 重置绘制中间量
        this.tip.show('单击开始绘制');
        // 左键点击事件
        this.handler.setInputAction(event => {
            const cartesian = CesiumCoord.ScreenToCartesian3(_this.viewer, event.position); // 屏幕坐标转世界坐标
            if (!Cesium.defined(cartesian)) return;
            _this.positionList.push(cartesian.clone());
            // 新增测量标注
            if (showMeasureLabel && !_this.labelEntity && _this.positionList.length > 2) {
                _this.labelEntity = _this.createLabelEntity();
                _this.entityCollection.add(_this.labelEntity, _this.groupId);
            }
            // 绘制多边形
            if (!_this.polygonEntry) {
                _this.polygonEntry = _this.createPolygonEntity();
                _this.entityCollection.add(_this.polygonEntry, _this.groupId);
            }
            // 绘制时的辅助线 临时的
            if (!_this.polylineEntity) {
                _this.polylineEntity = _this.createPolylineEntity();
                _this.viewer.entities.add(_this.polylineEntity);
            }
            _this.tip.changeText('右键结束绘制');
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        // 鼠标移动事件
        this.handler.setInputAction(event => {
            if (this.polygonEntry) {
                const cartesian = CesiumCoord.ScreenToCartesian3(_this.viewer, event.endPosition); // 屏幕坐标转世界坐标
                if (!Cesium.defined(cartesian)) return;
                const positionList = _this.positionList;
                if (positionList.length === 1) {
                    positionList.push(cartesian.clone());
                } else if (positionList.length >= 2) {
                    positionList.pop();
                    positionList.push(cartesian.clone());
                }
            }
            const { x, y } = event.endPosition;
            _this.tip.moveTipDOMPosition(x, y); // 改变 TipDOM 位置
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        // 右键点击事件
        this.handler.setInputAction(event => {
            _this.endDraw()
            const entities = this.entityCollection.getEntitiesByGroupId(_this.groupId); // 当前绘制的所有实体
            const pointList = CesiumCoord.cartesian3ToLonLatHeightArray(_this.positionList); // 转化为经纬度坐标
            resolve({
                entities,
                positionList: JSON.parse(JSON.stringify(_this.positionList)), // 当前绘制的点坐标集合
                pointList
            });
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    });
};
